using System.Linq.Expressions;
using System.Diagnostics.Contracts;

namespace Charisma.Linq
{
  public static class ExpressionExtensions
  {
    /// <summary>
    /// Strips <see cref="Expression.Quote"/> expressions.
    /// </summary>
    /// <param name="expression">The expression.</param>
    public static LambdaExpression StripQuotes(this Expression expression)
    {
      Contract.Requires(expression != null);
      while (expression.NodeType == ExpressionType.Quote)
        expression = ((UnaryExpression)expression).Operand;
      return (LambdaExpression)expression;
    }


    /// <summary>
    /// Strips <see cref="ExpressionType.Convert"/> and <see cref="ExpressionType.TypeAs"/>.
    /// </summary>
    /// <param name="expression">The expression.</param>
    public static Expression StripCasts(this Expression expression)
    {
      Contract.Requires(expression != null);
      while (expression.NodeType == ExpressionType.Convert
        || expression.NodeType == ExpressionType.TypeAs)
        expression = ((UnaryExpression)expression).Operand;
      return expression;
    }

    public static bool IsAnonymousConstructor(this Expression expression)
    {
      return expression != null && expression.NodeType == ExpressionType.New && expression.Type.IsAnonymous();
    }
  }
}